import React, { useRef, useEffect } from 'react';
import { useFrame, useThree } from '@react-three/fiber';
import { PointerLockControls } from '@react-three/drei';
import * as THREE from 'three';
import { WALLS, ROOM_BOUNDS } from './walls';
import { setMiniState } from './minimapStore';

const Player: React.FC = () => {
  const { camera } = useThree();
  const moveForward = useRef(false);
  const moveBackward = useRef(false);
  const moveLeft = useRef(false);
  const moveRight = useRef(false);
  const velocity = useRef(new THREE.Vector3());
  // 保留最小状态，仅使用速度与跳跃量
  const onGround = useRef(true);
  const jumpVelocity = useRef(0);
  

  // 使用共享墙段数据
  const wallBoxes = useRef<Array<[number, number, number, number]>>([]);
  // keep in sync with WALLS (if runtime hot-reloaded)
  wallBoxes.current = WALLS.map(w => [w.cx, w.cz, w.sx, w.sz]);

  function collideAxis(next: number, fixedOther: number, axis: 'x' | 'z'): number {
    const radius = 0.5; // 玩家半径略增，减少穿透
    for (const [cx, cz, sx, sz] of wallBoxes.current) {
      const hx = sx / 2 + radius;
      const hz = sz / 2 + radius;
      const minX = cx - hx, maxX = cx + hx;
      const minZ = cz - hz, maxZ = cz + hz;
      if (axis === 'x') {
        if (fixedOther >= minZ && fixedOther <= maxZ && next >= minX && next <= maxX) return NaN; // 阻挡
      } else {
        if (fixedOther >= minX && fixedOther <= maxX && next >= minZ && next <= maxZ) return NaN; // 阻挡
      }
    }
    return next;
  }

  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      switch (event.code) {
        case 'KeyW':
          moveForward.current = true;
          break;
        case 'KeyS':
          moveBackward.current = true;
          break;
        case 'KeyA':
          moveLeft.current = true;
          break;
        case 'KeyD':
          moveRight.current = true;
          break;
        case 'Space':
          // 单次跳跃，不飞天
          if (onGround.current) {
            jumpVelocity.current = 6; // 跳跃初速度（可调）
            onGround.current = false;
          }
          break;
      }
    };

    const handleKeyUp = (event: KeyboardEvent) => {
      switch (event.code) {
        case 'KeyW':
          moveForward.current = false;
          break;
        case 'KeyS':
          moveBackward.current = false;
          break;
        case 'KeyA':
          moveLeft.current = false;
          break;
        case 'KeyD':
          moveRight.current = false;
          break;
      }
    };

    document.addEventListener('keydown', handleKeyDown);
    document.addEventListener('keyup', handleKeyUp);

    return () => {
      document.removeEventListener('keydown', handleKeyDown);
      document.removeEventListener('keyup', handleKeyUp);
    };
  }, []);

  useFrame((_, delta) => {
    const moveSpeed = 6; // 再提升为常速步行
    const gravity = 20; // 重力


    // 基于相机朝向的本地方向向量
    const forward = new THREE.Vector3();
    camera.getWorldDirection(forward);
    forward.y = 0; // 限制在水平面
    forward.normalize();
    // 以视角为基准的右向量：right = up × forward
    const right = new THREE.Vector3().crossVectors(new THREE.Vector3(0, 1, 0), forward).normalize();

    // 移动位移（不再累计水平速度，保证恒定慢速）
    const moveVec = new THREE.Vector3();
    if (moveForward.current) moveVec.add(forward);
    if (moveBackward.current) moveVec.add(forward.clone().negate());
    // 调换 A/D：A 为向右，D 为向左
    if (moveLeft.current) moveVec.add(right);        // A
    if (moveRight.current) moveVec.add(right.clone().negate()); // D
    if (moveVec.lengthSq() > 0) moveVec.normalize().multiplyScalar(moveSpeed * delta);

    // 水平位移直接使用恒定慢速（去除“累积加速”）
    velocity.current.x = moveVec.x;
    velocity.current.z = moveVec.z;

    // 重力与跳跃（简单地面在 y=0 以上）
    if (!onGround.current) {
      jumpVelocity.current -= gravity * delta; // 受重力影响
    }
    camera.position.y += jumpVelocity.current * delta;
    if (camera.position.y <= 1.6) { // 视角高度≈1.6m，当作落地
      camera.position.y = 1.6;
      onGround.current = true;
      jumpVelocity.current = 0;
    }

    // 计算下一帧位置，加入房间边界限制，避免穿墙和卡死
    // 步进/扫掠：将位移分成若干小步，避免高速跨越薄墙
    const steps = 4;
    let nextX = camera.position.x;
    let nextZ = camera.position.z;
    for (let i = 0; i < steps; i++) {
      const stepX = velocity.current.x / steps;
      const stepZ = velocity.current.z / steps;
      const tryX = collideAxis(nextX + stepX, nextZ, 'x');
      if (!Number.isNaN(tryX)) nextX = tryX; // 碰撞则停止该轴
      const tryZ = collideAxis(nextZ + stepZ, nextX, 'z');
      if (!Number.isNaN(tryZ)) nextZ = tryZ;
    }
    // 更新边界与新房屋尺寸一致
    const halfW = ROOM_BOUNDS.W / 2 - 0.4;
    const halfL = ROOM_BOUNDS.L / 2 - 0.4;
    camera.position.x = Math.max(-halfW, Math.min(halfW, nextX));
    camera.position.z = Math.max(-halfL, Math.min(halfL, nextZ));

    // 推送位置与朝向到 minimap store
    const dir = new THREE.Vector3();
    camera.getWorldDirection(dir);
    setMiniState({ x: camera.position.x, z: camera.position.z, dx: dir.x, dz: dir.z });
  });

  return (
    <>
      <PointerLockControls />
    </>
  );
};

export default Player;
